package com.banmajio.config;

import com.banmajio.mapper.XtVolunteerInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
@Slf4j
public class SequenceGenerator {
    private final Map<String, SequenceHolder> sequenceHolders = new ConcurrentHashMap<>();
    private final int cacheSize = 10000; // 与数据库序列缓存一致

    @Autowired
    private XtVolunteerInfoMapper sequenceValueMapper;

    // 获取序列生成器实例
    public synchronized SequenceHolder getGenerator(String sequenceName) {
        return sequenceHolders.computeIfAbsent(sequenceName,
                name -> new SequenceHolder(name, cacheSize, sequenceValueMapper));
    }

    // 序列持有者内部类
    public static class SequenceHolder {
        private final String sequenceName;
        private final int cacheSize;
        private final XtVolunteerInfoMapper sequenceValueMapper;
        private final AtomicLong currentValue = new AtomicLong();
        private final AtomicLong maxValue = new AtomicLong();

        public SequenceHolder(String sequenceName, int cacheSize, XtVolunteerInfoMapper sequenceValueMapper) {
            this.sequenceName = sequenceName;
            this.cacheSize = cacheSize;
            this.sequenceValueMapper = sequenceValueMapper;
            refreshCache(); // 初始化缓存
        }

        // 获取下一个序列值
        public synchronized long getNextValue() {
            if (currentValue.get() >= maxValue.get()) {
                refreshCache();
            }
            return currentValue.incrementAndGet();
        }

        private void refreshCache() {
            long nextValue = sequenceValueMapper.getNextValue(sequenceName, cacheSize);
            currentValue.set(nextValue);
            maxValue.set(nextValue + cacheSize);
            log.info("序列 {} 缓存已刷新，当前值: {}, 最大值: {}",
                    sequenceName, currentValue.get(), maxValue.get());
        }
    }
}
